home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ahoy 1989 February
/
Ahoy_Magazine_89-02_1989_Double_L.d64
/
Dio Solver
(
.txt
)
< prev
next >
Wrap
Commodore BASIC
|
2022-10-26
|
4KB
|
115 lines
1 rem =================================
2 rem
3 rem diophantine solver
4 rem rupert report #62
5 rem ---------------------------------
6 rem solve equations of the form
7 rem ax + by = c for x and y
8 rem where all terms are integers
9 rem =================================
10 gosub 100 :rem initialize
20 gosub 300 :rem get a,b,c
30 gosub 1000 :rem make a & b positive
40 gosub 2000 :rem convert a/b to continued fraction and get gcf(a,b)
50 gosub 3000 :rem table of convergents
60 gosub 4000 :rem find t for x,y > 0
70 gosub 5000 :rem find x,y for given t
90 end
99 rem --------------------------------
100 rem -- initialize & input variables
110 dim p(20),q(20),f(20)
120 def fndiv(b)=int(a/b) :rem integer division
130 def fnmod(b)=int(a-b*fndiv(b)) :rem mod function
140 def fnii(z)=(z=int(z)) :rem true if z is integer
150 def fnmi(x)=sgn(x)*int(abs(x)) :rem make integer
160 def fnx(t)=c*q0-snb*b*t :rem x(t)
170 def fny(t)=a*t-snb*c*p0 :rem y(t)
175 print "[147]"
180 print: print "enter non-0 integer coefficients a,b,c"
190 print "for equation ax + by = c:"
200 input a,b,c
210 if not (fnii(a) and fnii(b) and fnii(c)) then print"integers only": goto 180
220 if a=0 or b=0 or c=0 then print"non-zero integers only": goto 180
230 print "[147]equation is ";a;"* x + ";b;"* y = ";c
240 print
250 a0=a: b0=b: c0=c: rem save originals
260 return
300 rem -- convert to positive integers
310 snb=1 :rem sign of b
320 if a<0 then a=-a: b=-b: c=-c :rem make a>0
330 if b<0 then b=-b: snb=-1 :rem make b>0
340 a1=a: b1=b: c1=c :rem save working values
350 return
360 rem --------------------------------
1000 rem convert a/b to continued fraction f(n) and find gcf
1010 rem a/b = f(n) remainder m
1020 n=1 :rem number of terms
1030 f(n)=fndiv(b) :rem integer division
1040 m=fnmod(b) :rem remainder
1050 if m=0 then 1080 :rem done
1060 a=b: b=m: n=n+1
1070 goto 1030
1080 if fnii(n/2) then 1110 :rem n/2 is integer::n is even
1090 f(n)=f(n)-1 :rem convert to even number of terms
1100 f(n+1)=1: n=n+1
1110 gcf=b :rem final divisor is gcf of a,b
1120 a=a1: b=b1: c=c1 :rem restore working values
1130 rem -----next line prints continued fraction for a/b
1140 print a; "/"; b; "= [";: for k=1 to n: print f(k);: next k: print "]"
1150 print " gcf ("; a; ","; b; ") ="; gcf: print
1160 return
1170 rem -------------------------------
2000 rem --reduce eqn by gcf if possible
2010 if gcf=1 then 2050
2020 if fnii(c/gcf) then goto 2040
2030 print "no solutions. c is not divisible by gcf of a and b": end
2040 a=a1/gcf: b=b1/gcf: c=c1/gcf
2050 return
2060 rem -------------------------------
3000 rem -- table of convergents of a/b
3010 p(0)=0: p(1)=1
3020 q(0)=1: q(1)=0
3030 rem print "convergents p,q:"
3040 for k=2 to n+1
3050 p(k)=f(k-1)*p(k-1)+p(k-2)
3060 q(k)=f(k-1)*q(k-1)+q(k-2)
3070 rem print p(k),q(k)
3080 next k
3090 p0=p(n): q0=q(n)
3100 return
3110 rem ------------------------------
4000 rem -- show results
4010 print: print "x and y as functions of t :"
4020 print " (t = 0, +/-1, +/-2, ...)": print
4030 sn$=") - (": if snb=-1 then sn$=") + ("
4040 print " x = ("; c*q0; sn$; b; "* t )"
4050 print " y = ("; a; "* t "; sn$; c*p0; ")"
4060 print: print "values of t for x & y > 0:"
4070 tx=snb*c*q0/b
4080 tx$=" < ": if snb=-1 then tx$=" > "
4090 ty=snb*c*p0/a: ty$=" > "
4100 print " for x>0: t"; tx$; tx
4110 print " for y>0: t"; ty$; ty
4120 if snb=-1 then 4200
4130 rem find t for t<tx and t>ty
4140 if tx < ty then print "no integer solutions for x>0 and y>0": goto 4230
4150 ta=int(tx): if ta=tx then ta=ta-1
4160 tb=int(ty)+1
4170 if ta<tb then print "no integer solutions": goto 4230
4180 if ta=tb then print "only solution is t = "; ta: goto 4230
4190 print "t is any integer from "; tb; " to "; ta: goto 4230
4200 rem find t for t>tx and t>ty
4210 mn=int(tx)+1: if ty>tx then mn=int(ty)+1
4220 print "t is any integer greater than or equal to "; mn
4230 print
4240 return
4250 rem ------------------------------
5000 rem --find x,y for given t
5010 input "what value of t";t
5020 print " x is ";fnx(t)
5030 print " y is ";fny(t)
5040 print: input"more [y,n]y[157][157][157]"; a$
5050 if a$="n" then return
5060 print "[145] ": print"[145]";
5070 goto 5010